package com.eh.springDataRedis.impl;

import com.eh.model.User;
import com.eh.springDataRedis.UserRedisTemplateService;
import com.eh.springDataRedis.constant.CacheConstant;
import com.eh.springDataRedis.dto.UserRedisRequest;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.testng.Assert;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Created by David Li on 2016/5/10.
 */
@Service
public class UserRedisTemplateServiceImpl implements UserRedisTemplateService {

    @Autowired
    private RedisTemplate<String, User> redisTemplate;

    @Override
    public String getUserDetailKeyName(UserRedisRequest userRedisRequest) {
        String id = userRedisRequest.getId();
        Long companyId = userRedisRequest.getCompanyId();
        String group = userRedisRequest.getGroup();

        Assert.assertNotNull(id);
        Assert.assertNotNull(companyId);

        StringBuilder keyName = new StringBuilder(CacheConstant.USER).append(":");

        if (group != null) {
            keyName.append(group).append(":");
        }

        return keyName.append(companyId).append(":").append(id).toString();
    }

    @Override
    public void updateUser(UserRedisRequest userRedisRequest, User user) {
        String keyName = getUserDetailKeyName(userRedisRequest);
        if (redisTemplate.opsForValue().get(keyName) == null) {
            redisTemplate.expire(keyName, 2, TimeUnit.HOURS);
        }
        redisTemplate.opsForValue().set(keyName, user);
    }

    @Override
    public User getUser(UserRedisRequest userRedisRequest) {
        return redisTemplate.opsForValue().get(getUserDetailKeyName(userRedisRequest));
    }

    @Override
    public String getUserAggregationKeyName(UserRedisRequest userRedisRequest) {
        Long companyId = userRedisRequest.getCompanyId();
        String group = userRedisRequest.getGroup();

        Assert.assertNotNull(companyId);
        Assert.assertNotNull(group);

        StringBuilder keyName = new StringBuilder(CacheConstant.USER_AGGREGATION).append(":");

        return keyName.append(group).append(":").append(companyId).toString();
    }

    @Override
    public void updateUserAggregation(UserRedisRequest userRedisRequest, List<User> users) {
        if (CollectionUtils.isNotEmpty(users)) {
            String keyName = getUserAggregationKeyName(userRedisRequest);
            if (redisTemplate.opsForList().range(keyName, 0, -1).size() == 0) {
                redisTemplate.expire(keyName, 2, TimeUnit.HOURS);
            }
            for (User user : users) {
                redisTemplate.opsForList().rightPush(keyName, user);
            }
        }
    }

    @Override
    public List<User> getUserAggregation(UserRedisRequest userRedisRequest) {
        String keyName = getUserAggregationKeyName(userRedisRequest);
        List<User> users = redisTemplate.opsForList().range(keyName, 0, -1);
        return users;
    }
}
